import { _decorator, Animation, AudioClip, AudioSource, BoxCollider, Color, Component, EventMouse, find, geometry, input, Input, instantiate, Prefab, resources, Sprite, sys, tween, Vec3} from 'cc';
import { GLOBALVar } from './GlobalVar';
import { CardGenerator } from './CardGenerate';
import { GLOBALPOP } from './GlobalPop';
import { WebSocketManager } from './WebSocketManager';
import { GLOBALUtil } from './GlobalUtil';
const { ccclass, property } = _decorator;

@ccclass('CardClickManager')
export class CardClickManager extends Component {
    @property({type: AudioClip, tooltip: "点击音效"})
    private Audio_000: AudioClip | null = null;
    @property({type: Number, tooltip: "卡牌种类"})
    private CardType: number;
    //卡牌是否可以点击
    private IsCardCanClick: Boolean = false;
    //卡牌被射线照射到的次数（上下左右中），大于五次的可点击
    private CardRayCount: number = 0;

    // 卡牌音效组件
    private ClickAudio : AudioSource | null = null;
    start() {

    }

    update(deltaTime: number) {
        
    }
    protected onLoad(): void {
        this.node.on(Input.EventType.TOUCH_END, () => {
            this.onClick()
        })

        this.ClickAudio = this.node.addComponent(AudioSource);
        this.ClickAudio.clip = this.Audio_000;
    }

    onClick() {
        if (this.IsCardCanClick) {
            this.ClickAudio.play();
            let IsAnyCardDestroy = false;
            //引用卡牌数据
            let CardsInMap = CardGenerator.getCardsInMap();
            let CardsInSlot = GLOBALVar.getCardInSlot();
            const POS = this.node.getWorldPosition();   //在移动之前获取坐标
            this.node.getComponent(BoxCollider).enabled = false; //禁用点击卡牌的碰撞体，从而避免被射线检测到
            //把相同的卡牌相邻摆放
            if (CardsInSlot.length === 0) {
                CardsInSlot.push(this.node);
                tween(this.node).to(0.2, {position: new Vec3(-214 + 85 * (CardsInSlot.length - 1), -570, this.node.position.z)}).start();
            } else {
                for (let i = 0; i < CardsInSlot.length; i++) {
                    const CARD = CardsInSlot[i];
                    if (i === CardsInSlot.length - 1) {
                        CardsInSlot.push(this.node);
                        tween(this.node).to(0.2, {position: new Vec3(-214 + 85 * (CardsInSlot.length - 1), -570, this.node.position.z)}).start();
                        break;
                    } else if (CARD.getComponent(CardClickManager).CardType === this.CardType) {
                        let step: number = 0; //记录卡牌插入的位置 + 1用于把右边的卡牌向后移动
                        //判断后一张牌是否是同类，如果是的话那就把这张新的牌排到后面
                        if (CardsInSlot[i+1].getComponent(CardClickManager).CardType !== this.CardType) {
                            CardsInSlot.splice(i+1, 0, this.node);
                            tween(this.node).to(0.2, {position: new Vec3(-214 + 85 * (i+1), -570, this.node.position.z)}).start();
                            step = i + 1 + 1;
                        } else {
                            CardsInSlot.splice(i+2, 0, this.node);
                            tween(this.node).to(0.2, {position: new Vec3(-214 + 85 * (i+2), -570, this.node.position.z)}).start();
                            step = i + 1 + 2;
                        }
                        //把右边的牌往后移,倒着移动
                        for (let j = CardsInSlot.length - 1; j >= step; j--) {
                            tween(CardsInSlot[j]).to(0.2, {position: new Vec3(-214 + 85 * j, -570, this.node.position.z)}).start();
                        }
                        break;
                    }
                }
            }
            CardGenerator.updateCardCover(POS);
            this.SetCardCanClick(false);
            //判断卡槽内卡牌能否消除
            let TypeMap = new Map();
            CardsInSlot.forEach((card) => {
                let type = card.getComponent(CardClickManager).CardType;
                TypeMap.set(type, TypeMap.has(type) ? TypeMap.get(type) + 1 : 1);
            })
            TypeMap.forEach((value, key) => {
                if (value === 3) {
                    IsAnyCardDestroy = true;
                    let DeArr = [];   //暂存需要删除的节点
                    CardsInSlot.forEach((card) => {
                        if (card.getComponent(CardClickManager).CardType === key) {
                            DeArr.push(card);
                        }
                    })

                    //每次消除都往服务端发送消息，用于计算收益（只在web平台使用，详见MenuSceneManager.ts中的解释）
                    if (sys.isBrowser) {
                        const wsManager = WebSocketManager.getInstance();
                        wsManager.send("FirstConnect", JSON.stringify({
                            type: "card_elimination",
                            token: localStorage.getItem("token"),
                        }));
    
                        const handleMessage = (data: string) => {
                            const jsonData = JSON.parse(data);
                            // 在这里进行消息处理，例如解析JSON数据
                            try {
                                if (jsonData.type === "coins_updated") {
                                    resources.load('Prefabs/CoinAddNode', Prefab, (err, prefab) => {
                                        const coinAddNode = instantiate(prefab);
                                        const parentNode = find('Canvas');
                                        parentNode.addChild(coinAddNode);
                                        coinAddNode.getComponent(Animation).play();
                                        coinAddNode.getComponent(Animation).on(Animation.EventType.FINISHED, () => {
                                            coinAddNode.destroy();
                                        })
                                    })
                                }
                            } catch (error) {
                                console.error('Error parsing JSON:', error);
                            }
                        };
    
                        wsManager.on("FirstConnect", handleMessage);
                    }
                    
                    //原生平台使用XMLHttpRequest增加金币(不能使用阻塞IO操作，不然会因为网速问题导致卡牌的消除逻辑出bug)
                    if (sys.isNative) {
                        try {
                            const response = GLOBALUtil.addCoin();
                            resources.load('Prefabs/CoinAddNode', Prefab, (err, prefab) => {
                                const coinAddNode = instantiate(prefab);
                                const parentNode = find('Canvas');
                                parentNode.addChild(coinAddNode);
                                coinAddNode.getComponent(Animation).play();
                                coinAddNode.getComponent(Animation).on(Animation.EventType.FINISHED, () => {
                                    coinAddNode.destroy();
                                })
                            })
                        } catch (error) {
                            console.log("Error occurred when add coin by XMLHttpRequest");
                        }
                    }
                    
                    DeArr.forEach((card) => {
                        CardsInSlot.splice(CardsInSlot.indexOf(card), 1);
                        CardsInMap.splice(CardsInMap.indexOf(card), 1);
                        setTimeout(() => {
                            card.destroy();
                        }, 200);
                    })
                }
            })
            // 重新排序, 卡牌移动动画结束后再执行,否则卡牌就会直接被设定位置！
            if (IsAnyCardDestroy) {
                setTimeout(() => {
                    CardsInSlot.forEach((card, index) => {
                        tween(card).to(0.2, {position: new Vec3(-214 + 85 * index, -570, card.position.z)}).start();
                    })
                }, 200);
            }
            //卡槽满了
            if (CardsInSlot.length === 7) {
                GLOBALPOP.setGameState(0);
            }
            //卡牌全部消除完毕
            if (CardsInMap.length === 0) {
                if (GLOBALVar.getClassicModeLevel() <= 2) {
                    CardGenerator.playYouPass();
                }
                GLOBALVar.setClassicModeLevel(GLOBALVar.getClassicModeLevel() + 1);
                CardGenerator.generateLevel();
            }
        } else {
            return;
        }
    }

    //设置卡牌是否可以点击
    public SetCardCanClick(canClick: Boolean) {
        this.IsCardCanClick = canClick;
        if (this.IsCardCanClick) {
            const COVER = this.node.getChildByName("Cover");
            tween(COVER.getComponent(Sprite)).to(0.1, {color: new Color(255, 255, 255, 0)}).start();
        }
    }
    //获取卡牌激活状态
    public GetCardCanClick(): Boolean {
        return this.IsCardCanClick;
    }
    public getCardrayCount(): number {
        return this.CardRayCount;
    }
    public setCardrayCount(count: number) {
        this.CardRayCount = count;
        if (this.CardRayCount >= 4) { 
            this.SetCardCanClick(true);
            const sp = this.node.getChildByName("Cover").getComponent(Sprite);
            tween(sp).to(0.5, {color: new Color(255, 255, 255, 0)}).start();
        }
    }
}


